home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 1
/
Cream of the Crop 1.iso
/
PROGRAM
/
UUPC11QS.ARJ
/
UUPOLL.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-10-18
|
21KB
|
617 lines
/*
Program: uupoll.c 22 September 1989
Author: Andrew H. Derbyshire
108 Decatur St
Arlington, MA 02174
Internet: help@kew.com
Function: Performs autopoll functions for UUCICO
Language: Borland C++ 2.0
Usage: uupoll [-r 0] [-f hhmm] [-i hhmm|0400 ] [-d hhmm]
[-a hhmm] [-x debug] [-s systems]
Where:
-r 0 specifies that UUCICO is to run into
passive mode when waiting to poll out
-r 1 specifies that UUCICO will not run in passive
mode while waiting to poll out, but polling
out will occur.
-f hhmm is the first time in the day that uuio
is to poll out. If omitted, polling
begins after the interval specified with
-i.
-i hhmm the interval the UUCICO is to poll out
at. If omitted, a period of 4 hours
will be used.
-d hhmm Terminate polling after hhmm. Default is
not to terminate.
-a hhmm Automatically poll actively using the system
name "any" after any successfully inbound
poll if hhmm have past since last poll. hhmm
may be 0000.
In addition, the following flags will be passed
to UUCICO:
-s system system name to poll. By default,
UUCICO will be invoked with '-s all'
followed by '-s any'.
-x n debug level. The default level
is 1.
*/
#include <assert.h>
#include <ctype.h>
#include <dos.h>
#include <limits.h>
#include <process.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <conio.h>
#include <direct.h>
#ifdef __TURBOC__
#include <alloc.h>
unsigned _stklen = 2048; /* Reduce memory usage */
unsigned _heaplen = 2048; /* Reduce memory usage */
#else
#ifndef FAMILYAPI
static int setcbrk(char state);
#endif
#endif
#include "getopt.h"
#include "lib.h"
#include "timestmp.h"
#include "ssleep.h"
#ifdef DEBUG
#define printmsg(a,b,c) /* printmsg(a,b,c) */
#include "arpadate.h"
#include "arpadate.c"
#endif
typedef int hhmm;
#define hhmm2sec(HHMM) ((time_t)(((HHMM / 100) * 60L) + \
(time_t)(HHMM % 100)) * 60L)
static int active(char *Rmtname, int debuglevel);
static void busywork( time_t next);
static int execute( char *command );
static time_t nextpoll( hhmm first, hhmm interval );
static boolean notanumber( char *number);
static int passive( time_t next, int debuglevel );
static void usage( char *name );
static hhmm firstpoll(hhmm interval);
static void uuxqt( int debuglevel);
static time_t now; /* Current time, updated at start of
program and by busywork() and
execute() */
/*--------------------------------------------------------------------*/
/* m a i n */
/* */
/* main program */
/*--------------------------------------------------------------------*/
main( int argc , char *argv[] )
{
int option;
hhmm first = - 1;
hhmm interval = -1;
time_t duration = LONG_MAX;
int nopassive = 2;
boolean autoforward = TRUE;
boolean done = FALSE;
time_t autowait;
char *Rmtname = NULL;
int debuglevel = 1;
int returncode = 0;
#ifndef FAMILYAPI
boolean cbrk;
#endif
banner(argv);
tzset();
time( &now );
while((option = getopt(argc, argv, "a:d:f:i:s:r:x:")) != EOF)
switch(option)
{
/*--------------------------------------------------------------------*/
/* Automatically poll "any" after an incoming phone call */
/*--------------------------------------------------------------------*/
case 'a':
autoforward = TRUE;
if (notanumber(optarg))
usage( argv[0] );
autowait = hhmm2sec( atoi(optarg) );
break;
/*--------------------------------------------------------------------*/
/* First time to poll */
/*--------------------------------------------------------------------*/
case 'f':
if (notanumber(optarg))
usage( argv[0] );
first = atoi(optarg);
if ( interval == -1 )
interval = 400;
break;
/*--------------------------------------------------------------------*/
/* Interval to poll */
/*--------------------------------------------------------------------*/
case 'i':
if (notanumber(optarg))
usage( argv[0] );
interval = atoi(optarg);
nopassive = min(1,nopassive);
break;
/*--------------------------------------------------------------------*/
/* Time (duration) to poll */
/*--------------------------------------------------------------------*/
case 'd':
if (notanumber(optarg))
usage( argv[0] );
duration = atoi(optarg);
break;
/*--------------------------------------------------------------------*/
/* System name to poll */
/*--------------------------------------------------------------------*/
case 's':
Rmtname = strdup(optarg);
break;
/*--------------------------------------------------------------------*/
/* Debug level */
/*--------------------------------------------------------------------*/
case 'x':
if (notanumber(optarg))
usage( argv[0] );
debuglevel = atoi(optarg);
break;
/*--------------------------------------------------------------------*/
/* Passive polling option */
/*--------------------------------------------------------------------*/
case 'r':
if (notanumber(optarg))
usage( argv[0] );
nopassive = atoi(optarg);
break;
/*--------------------------------------------------------------------*/
/* Help */
/*--------------------------------------------------------------------*/
default:
case '?':
usage( argv[0] );
} /* switch */
/*--------------------------------------------------------------------*/
/* Terminate with error if too many arguments */
/*--------------------------------------------------------------------*/
if (optind != argc)
{
puts("Extra parameters on command line.");
usage( argv[0] );
}
/*--------------------------------------------------------------------*/
/* Terminate if neither active polling nor passive polling requested */
/*--------------------------------------------------------------------*/
if ( nopassive == 2 && (first < 0))
{
puts("Must specify -r 0, -f hhmm, or -i hhmm");
usage( argv[0] );
}
if ( (interval > 0) && (first < 0))
first = firstpoll(interval);
/*--------------------------------------------------------------------*/
/* If running under MS-DOS, enable Cntrl-Break. */
/*--------------------------------------------------------------------*/
#ifndef FAMILYAPI
#ifdef __TURBOC__
cbrk = getcbrk(); /* Get original Cntrl-Break setting */
if (!cbrk)
setcbrk(1); /* Turn it on to allow abort */
#else /*dmw*/
cbrk = setcbrk(1); /* Turn it on to allow abort; get previous state */
printf("BREAK ON has been set\n");
#endif
#endif
/*--------------------------------------------------------------------*/
/* If a quitting internal was specified, convert it to an */
/* absolute time */
/*--------------------------------------------------------------------*/
if (duration != LONG_MAX)
{
duration = hhmm2sec( duration ) + (now / 60L) * 60L;
/* Round to next lower minute */
printf("Will terminate upon completion of first event \
after %s", ctime(&duration));
} /* if */
/*--------------------------------------------------------------------*/
/* Beginning of main loop */
/*--------------------------------------------------------------------*/
while ( !done && (duration > now))
{
time_t next = LONG_MAX;
time_t autonext = now + autowait;
time_t wait = 10; /* Time to wait after first panic() */
if (first >= 0)
next = nextpoll(first,interval);
else
next = duration;
while ((now < next) && ! done )
{
if (nopassive)
busywork(next);
else {
time_t spin;
returncode = passive(next,debuglevel);
if (returncode == 69 ) /* Error in UUCICO? */
{ /* Yes --> Allow time to fix it */
spin = now + wait; /* Figure next wait */
wait *= 2 ; /* Double wait for next time */
busywork( spin > next ? next : spin );
/* But only wait till next poll */
} /* if (returncode == 69 ) */
else {
wait = 10;
if ((returncode == 0) && autoforward && (now > autonext))
{
returncode = active("any",debuglevel);
autonext = now + autowait;
} /* if */
} /* else */
if ( (now > duration) && (now < next))
done = TRUE;
else if ( returncode == 100 )
done = TRUE;
} /* else */
} /* while */
if ( ! done && (first >= 0) )
{
returncode = active(Rmtname,debuglevel);
if ( returncode == 100 )
done = TRUE;
} /* if ( ! done && (first >= 0) ) */
} /* while */
/*--------------------------------------------------------------------*/
/* End of main loop */
/*--------------------------------------------------------------------*/
uuxqt( debuglevel ); /* One last call to UUXQT */
#ifndef FAMILYAPI
if (!cbrk)
setcbrk(0); /* Restore original Cntrl-Break setting */
#endif
return(returncode);
} /* main */
/*--------------------------------------------------------------------*/
/* a c t i v e */
/* */
/* Perform an active (outgoing) poll of other hosts */
/*--------------------------------------------------------------------*/
static active(char *Rmtname, int debuglevel)
{
int result;
if (Rmtname == NULL) /* Default? */
{ /* Yes --> do -s all and -s any */
if (active("all",debuglevel) < 100)
return active("any",debuglevel);
else
return 100;
}
else {
char buf[128];
sprintf(buf,"uucico -r 1 -s %s -x %d",Rmtname,debuglevel);
result = execute(buf);
if ( result == 0 )
uuxqt( debuglevel );
return result;
}
} /* active */
/*--------------------------------------------------------------------*/
/* b u s y w o r k */
/* */
/* Waits for next time to poll without answering the telephone. */
/* Maybe we should at least beep on the hour? :-) */
/*--------------------------------------------------------------------*/
static void busywork( time_t next)
{
time_t naptime;
time_t hours, minutes, seconds;
naptime = next - now;
hours = (naptime / 3600) % 24; /* Get pretty time to display... */
minutes = (naptime / 60) % 60;
seconds = naptime % 60;
printf("Going to sleep for %02ld:%02ld:%02ld, next poll is %s",
hours, minutes, seconds, ctime(&next) );
ssleep( naptime );
time( & now );
}
/*--------------------------------------------------------------------*/
/* e x e c u t e */
/* */
/* Executes a command via a spawn() system call. This avoids */
/* the storage overhead of COMMAND.COM and returns the actual */
/* return code from the command executed. */
/* */
/* Note that this does not allow quoted command arguments, which */
/* not a problem for the intended argv[0]s of UUCICO. */
/*--------------------------------------------------------------------*/
static int execute( char *command )
{
char *argv[20];
int argc = 0;
int result;
#ifdef DEBUG
FILE *stream = NULL;
#endif
printf("Executing command: %s\n",command);
#ifdef DEBUG /* ahd */
stream = fopen("UUPOLL.LOG","a");
if (stream == NULL)
{
perror("UUPOLL.LOG");
abort();
} /* if */
fprintf(stream, "%s: %s\n",arpadate(), command);
fclose(stream);
#endif /* DEBUG */
argv[argc] = strtok(command," \t");
while ( argv[argc++] != NULL )
argv[argc] = strtok( NULL," \t");
result = spawnvp(P_WAIT , argv[0] , argv );
if ( result < 0 )
{
printf("\a\nCommand \"%s\" failed!\n\a", argv[0]);
abort();
}
time( & now );
return result;
}
/*--------------------------------------------------------------------*/
/* n e x t p o l l */
/* */
/* Returns next time to poll in seconds */
/* */
/* modified 14 October 1990 By Ed Keith. */
/* modified 4 November 1990 by Drew Derbyshire. */
/*--------------------------------------------------------------------*/
static time_t nextpoll( hhmm first, hhmm interval )
{
time_t sfirst;
time_t sinterval = hhmm2sec( interval );
time_t today;
time_t tomorrow;
struct tm *time_record; /* Ed K. 10/14/1990 */
time_record = localtime(&now); /* Ed K. 10/14/1990 */
time_record->tm_sec = 0; /* Ed K. 10/14/1990 */
time_record->tm_min = 0; /* Ed K. 10/14/1990 */
time_record->tm_hour= 0; /* Ed K. 10/14/1990 */
today = mktime(time_record);
tomorrow = today + 86400;
sfirst = today + hhmm2sec(first);
while (sfirst < now)
sfirst += sinterval;
if (sfirst > tomorrow)
sfirst = tomorrow + hhmm2sec(first);
return sfirst;
} /* nextpoll */
/*--------------------------------------------------------------------*/
/* f i r s t p o l l */
/* */
/* Determine first time to poll if not specified */
/*--------------------------------------------------------------------*/
static hhmm firstpoll(hhmm interval)
{
struct tm *time_record;
time_t sfirst;
hhmm first;
time_record = localtime(&now);
sfirst = ((time_t) time_record->tm_hour * 3600L +
(time_t) time_record->tm_min * 60L);
sfirst = sfirst % hhmm2sec(interval);
first = (hhmm) ((sfirst / 3600L) * 100L + (sfirst % 3600L) / 60L);
printf("First polling time computed to be %-2.2d:%-2.2d\n",
first / 100, first % 100);
return first;
} /* firstpoll */
/*--------------------------------------------------------------------*/
/* n o t a n u m b e r */
/* */
/* Examines string, returns true if non-numeric */
/*--------------------------------------------------------------------*/
static boolean notanumber( char *start)
{
char *number = start;
while (*number != '\0')
{
if (!isdigit(*number))
{
printf("Parameter must be numeric, was %s\n",start);
return TRUE;
}
number++;
}
return FALSE;
} /* notanumber */
/*--------------------------------------------------------------------*/
/* p a s s i v e */
/* */
/* Invoke UUCICO in passive mode until next active poll (if any). */
/*--------------------------------------------------------------------*/
static int passive( time_t next, int debuglevel )
{
char buf[128]; /* Buffer for execute() commands */
int result;
sprintf(buf,"uucico -r 0 -x %d",debuglevel);
if (next > 0) /* Should we poll out? */
{ /* Yes --> Compute time to poll */
char xnow[5]; /* Current time as a string */
char then[5]; /* Next time to poll as a string */
struct tm *tm_now; /* Format time in integer values */
tm_now = localtime(&now); /* Get time broken down */
sprintf(xnow,"%02d%02d", tm_now->tm_hour, tm_now->tm_min);
/*--------------------------------------------------------------------*/
/* Format the time to stop polling. Note that to have the */
/* system actively poll at time x, we compute the window to */
/* passively poll to end at x-1, since the passive window will */
/* remain open until x-1 + 59 seconds. */
/*--------------------------------------------------------------------*/
if ( (next - now) > 120) /* Poll at least two minutes? */
next--; /* Yes --> End at start of the min */
tm_now = localtime(&next); /* Get time broken down */
sprintf(then,"%02d%02d", tm_now->tm_hour, tm_now->tm_min);
strcat(buf," -u Any");
strcat(buf,xnow);
strcat(buf,"-");
strcat(buf,then);
}
result = execute(buf);
if ( result == 0 )
uuxqt( debuglevel );
return result;
} /* passive */
/*--------------------------------------------------------------------*/
/* u u x q t */
/* */
/* Execute the UUXQT program to run files received by UUCICO */
/*--------------------------------------------------------------------*/
static void uuxqt( int debuglevel)
{
int result;
char buf[128]; /* Buffer for execute() commands */
sprintf(buf,"uuxqt -x %d", debuglevel);
result = execute(buf);
assert( result == 0 );
} /* uuxqt */
/*--------------------------------------------------------------------*/
/* u s a g e */
/* */
/* Report correct usage of the program and then exit. */
/*--------------------------------------------------------------------*/
static void usage( char *name )
{
printf("Usage:\t%s\
\t[-a hhmm] [-d hhmm] [-f hhmm] [-i hhmm] \n\
\t\t[-r 0 | 1] [-s system] [-x n]\n",name);
exit(4);
}
#ifndef FAMILYAPI
#ifndef __TURBOC__
/*
s e t c b r k
Enable Cntrl-Break
Written by Dave Watts
*/
static int setcbrk(char state)
{
union REGS inregs, outregs;
inregs.x.ax = 0x3302;
inregs.h.dl = state;
intdos(&inregs, &outregs);
return outregs.h.dl;
}
#endif
#endif